From a392ea0ca79dfb620bf837aafa731a0af55e9619 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Thu, 15 Dec 2005 20:38:44 +0100 Subject: [PATCH] Clear all shadow caches when return to real mode from protect mode. So that, if OS modify some page tables in real mode and then return to protect mode, no outdated shadow table be used because out of sync machanism do not work in real mode. Signed-off-by: Xiaofeng Ling --- xen/arch/x86/shadow32.c | 17 +++++++++++++++++ xen/arch/x86/shadow_public.c | 18 ++++++++++++++++++ xen/arch/x86/vmx.c | 1 + xen/include/asm-x86/shadow.h | 2 ++ 4 files changed, 38 insertions(+) diff --git a/xen/arch/x86/shadow32.c b/xen/arch/x86/shadow32.c index 7d517ec390..661aae27e7 100644 --- a/xen/arch/x86/shadow32.c +++ b/xen/arch/x86/shadow32.c @@ -2982,6 +2982,23 @@ void __update_pagetables(struct vcpu *v) } } +void clear_all_shadow_status(struct domain *d) +{ + shadow_lock(d); + free_shadow_pages(d); + free_shadow_ht_entries(d); + d->arch.shadow_ht = + xmalloc_array(struct shadow_status, shadow_ht_buckets); + if ( d->arch.shadow_ht == NULL ) { + printk("clear all shadow status:xmalloc fail\n"); + domain_crash_synchronous(); + } + memset(d->arch.shadow_ht, 0, + shadow_ht_buckets * sizeof(struct shadow_status)); + + free_out_of_sync_entries(d); + shadow_unlock(d); +} /************************************************************************/ /************************************************************************/ diff --git a/xen/arch/x86/shadow_public.c b/xen/arch/x86/shadow_public.c index ea220edde1..971b659c35 100644 --- a/xen/arch/x86/shadow_public.c +++ b/xen/arch/x86/shadow_public.c @@ -1747,6 +1747,24 @@ void shadow_sync_and_drop_references( shadow_unlock(d); } +void clear_all_shadow_status(struct domain *d) +{ + shadow_lock(d); + free_shadow_pages(d); + free_shadow_ht_entries(d); + d->arch.shadow_ht = + xmalloc_array(struct shadow_status, shadow_ht_buckets); + if ( d->arch.shadow_ht == NULL ) { + printk("clear all shadow status:xmalloc fail\n"); + domain_crash_synchronous(); + } + memset(d->arch.shadow_ht, 0, + shadow_ht_buckets * sizeof(struct shadow_status)); + + free_out_of_sync_entries(d); + shadow_unlock(d); +} + /* * Local variables: * mode: C diff --git a/xen/arch/x86/vmx.c b/xen/arch/x86/vmx.c index ff53fedea2..e8e6f8d0b2 100644 --- a/xen/arch/x86/vmx.c +++ b/xen/arch/x86/vmx.c @@ -1223,6 +1223,7 @@ static int vmx_set_cr0(unsigned long value) } } + clear_all_shadow_status(v->domain); if (vmx_assist(v, VMX_ASSIST_INVOKE)) { set_bit(VMX_CPU_STATE_ASSIST_ENABLED, &v->arch.arch_vmx.cpu_state); __vmread(GUEST_RIP, &eip); diff --git a/xen/include/asm-x86/shadow.h b/xen/include/asm-x86/shadow.h index b0c24dd895..b9a80068d2 100644 --- a/xen/include/asm-x86/shadow.h +++ b/xen/include/asm-x86/shadow.h @@ -1707,6 +1707,8 @@ static inline void update_pagetables(struct vcpu *v) } } +void clear_all_shadow_status(struct domain *d); + #if SHADOW_DEBUG extern int _check_pagetable(struct vcpu *v, char *s); extern int _check_all_pagetables(struct vcpu *v, char *s); -- 2.30.2